package common

import (
	"fmt"
	"strings"

	"gitee.com/tomatomeatman/golang-repository/bricks3/model/dbinfo"
	"gitee.com/tomatomeatman/golang-repository/bricks3/model/globalvariable"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/ginutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/sqlfactory"

	Log "github.com/cihub/seelog"
	"github.com/gin-gonic/gin"
)

var virtualController *VirtualController

type VirtualController struct {
}

/**
 * 初始化
 */
func init() {
	virtualController = &VirtualController{}
	globalvariable.Add("Module@VirtualController", virtualController)

	ginutil.AddUrl("/api/:module/*fun", virtualController.HandleCommonRequest, ginutil.GET, ginutil.POST, ginutil.PUT, ginutil.DELETE)

	// 文件上传下载
	ginutil.AddUrl("/down/:file", virtualController.HandleFileDownload, ginutil.GET)
	ginutil.AddUrl("/up/:file", virtualController.HandleFileUpload, ginutil.POST)
}

// HandleCommonRequest 处理通用请求
func (c *VirtualController) HandleCommonRequest(ctx *gin.Context) (bool, string, interface{}) {
	module := strings.TrimSpace(ctx.Param("module"))
	fun := strings.TrimSpace(ctx.Param("fun"))

	if module == "" {
		return false, ":module路径缺失", 9102
	}

	if fun == "" {
		return false, ":fun路径缺失", 9103
	}

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), module)
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	switch fun {
	case "/find/id":
		return c.FindById(ctx, entity)
	case "/find/key":
		return c.FindByKey(ctx, entity)
	case "/find/key/one":
		return c.FindByKeyOne(ctx, entity)
	case "/find/page":
		return c.FindPage(ctx, entity)
	case "/find/page/row":
		return c.FindPagRow(ctx, entity)
	case "/find/all":
		return c.FindAll(ctx, entity)
	case "/find/max":
		return c.FindMax(ctx, entity)
	case "/find/min":
		return c.FindMin(ctx, entity)
	case "/find/has":
		return c.FindHas(ctx, entity)
	case "/find/count":
		return c.FindCount(ctx, entity)
	case "/find/tree":
		return c.FindTree(ctx, entity)
	case "/find/group":
		return c.FindGroup(ctx, entity)
	case "/add/group":
		return c.AddToGroup(ctx, entity)
	case "/clear/cache":
		return c.ClearCache(ctx, entity)
	case "/add":
		return c.Add(ctx, entity)
	case "/adds":
		return c.Adds(ctx, entity)
	case "/edit":
		return c.Edit(ctx, entity)
	case "/edits":
		return c.Edits(ctx, entity)
	case "/del":
		return c.Del(ctx, entity)
	case "/dels":
		return c.Dels(ctx, entity)
	default:
		return false, "请求路径未定义", 9105
	}
}

// FindById 根据ID查询
func (c *VirtualController) FindById(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	id, ok := params[entity.KeyName()]
	if !ok {
		return false, "没有编号参数:" + entity.KeyName(), 9204
	}

	var fields []string
	if fieldsParam, ok := params["fields"].([]string); ok {
		fields = fieldsParam
	}

	return GetService(entity.DbName, entity.Name).FindById(ctx, entity, id, fields)
}

// FindByKey 根据条件查询多条
func (c *VirtualController) FindByKey(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	var findByPageParam dbinfo.FindByPageParam
	ginutil.GetParamsToBind(ctx, &findByPageParam)

	return GetService(entity.DbName, entity.Name).FindByKey(ctx, entity, findByPageParam.Fields, findByPageParam.Conditions, findByPageParam.Orders)
}

// FindByKeyOne 根据条件查询单条
func (c *VirtualController) FindByKeyOne(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	var fields []string
	if fieldsParam, ok := params["fields"].([]interface{}); ok {
		fields = make([]string, len(fieldsParam))
		for i, v := range fieldsParam {
			fields[i] = fmt.Sprintf("%v", v)
		}
	}

	return GetService(entity.DbName, entity.Name).FindByKeyOne(ctx, entity, fields, params)
}

// FindPage 分页查询
func (c *VirtualController) FindPage(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	var findByPageParam dbinfo.FindByPageParam
	ginutil.GetParamsToBind(ctx, &findByPageParam)
	return GetService(entity.DbName, entity.Name).FindPage(ctx, entity, &findByPageParam)
}

// FindPagRow 行查询
func (c *VirtualController) FindPagRow(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	id, ok := params[entity.KeyName()]
	if !ok {
		return false, "没有编号参数:" + entity.KeyName(), 9204
	}

	var fields []string
	if fieldsParam, ok := params["fields"].([]string); ok {
		fields = fieldsParam
	}

	return GetService(entity.DbName, entity.Name).FindById(ctx, entity, id, fields)
}

// FindAll 查询所有
func (c *VirtualController) FindAll(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	return GetService(entity.DbName, entity.Name).FindAll(ctx, entity)
}

// FindMax 查询最大值
func (c *VirtualController) FindMax(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	field, ok := params["field"].(string)
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	conditions, ok := params["conditions"].(map[string]interface{})

	return GetService(entity.DbName, entity.Name).FindMax(ctx, entity, field, conditions)
}

// FindMin 查询最小值
func (c *VirtualController) FindMin(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	field, ok := params["field"].(string)
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	conditions, ok := params["conditions"].(map[string]interface{})

	return GetService(entity.DbName, entity.Name).FindMin(ctx, entity, field, conditions)
}

// FindHas 查询是否存在
func (c *VirtualController) FindHas(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	field, ok := params["field"].(string)
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	value, ok := params["value"]
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	return GetService(entity.DbName, entity.Name).FindHas(ctx, entity, field, value)
}

// FindCount 查询数量
func (c *VirtualController) FindCount(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	return GetService(entity.DbName, entity.Name).FindCount(ctx, entity, params)
}

// FindTree 查询树形结构数据
func (c *VirtualController) FindTree(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	groupColumn := ginutil.GetParam(ctx, "groupColumn", "").(string)
	groupName := ginutil.GetParam(ctx, "groupName", "").(string)
	return GetService(entity.DbName, entity.Name).FindTree(ctx, entity, groupColumn, groupName)
}

// ClearCache 清理指定用户的缓存
func (c *VirtualController) ClearCache(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	user := ginutil.GetParam(ctx, "user", "").(string)           //取请求参数中的用户名
	cacheName := ginutil.GetParam(ctx, "cacheName", "").(string) //取请求参数中的缓存名
	return GetService(entity.DbName, entity.Name).ClearCache(ctx, entity, user, cacheName)
}

// FindGroup 查询组结构数据
func (c *VirtualController) FindGroup(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	groupColumn := ginutil.GetParam(ctx, "groupColumn", "english").(string) //分组名(树节点)所在字段名
	groupName := ginutil.GetParam(ctx, "groupName", "").(string)            //分组名(树节点)
	return GetService(entity.DbName, entity.Name).FindByGroup(ctx, entity, groupColumn, groupName)
}

// AddToGroup 添加数据到指定组下
func (c *VirtualController) AddToGroup(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数
	groupColumn := ginutil.GetParam(ctx, "groupColumn", "").(string)
	groupName := ginutil.GetParam(ctx, "groupName", "").(string)
	return GetService(entity.DbName, entity.Name).AddToGroup(ctx, entity, groupColumn, groupName, params)
}

// AddData 添加数据
func (c *VirtualController) Add(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	// data, ok := params["data"].(map[string]interface{})
	// if !ok {
	// 	return false, "从请求参数解析数据发生异常", 9001
	// }

	return GetService(entity.DbName, entity.Name).Add(ctx, entity, params)
}

// Adds 批量添加数据
func (c *VirtualController) Adds(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	data, ok := params["data"].([]map[string]interface{})
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	return GetService(entity.DbName, entity.Name).Adds(ctx, entity, data)
}

// Edit 更新数据
func (c *VirtualController) Edit(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	// conditions, err := GetService(entity.DbName, entity.Name).ParseConditions(params)
	// if err != nil {
	// 	Log.Error("从请求参数解析查询条件发生异常:", err.Error())
	// 	return false, "从请求参数解析查询条件发生异常", 9001
	// }

	// data, ok := params["data"].(map[string]interface{})
	// if !ok {
	// 	return false, "从请求参数解析数据发生异常", 9001
	// }

	// return GetService(entity.DbName, entity.Name).EditData(ctx, entity, conditions, data)
	return GetService(entity.DbName, entity.Name).Edit(ctx, entity, params)
}

// Edits 批量更新数据
func (c *VirtualController) Edits(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	updates, ok := params["updates"].([]struct {
		Conditions []dbinfo.QueryCondition
		Data       map[string]interface{}
	})
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	return GetService(entity.DbName, entity.Name).Edits(ctx, entity, updates)
}

// Del 删除数据
func (c *VirtualController) Del(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	return GetService(entity.DbName, entity.Name).Del(ctx, entity, params)
}

// Dels 批量删除数据
func (c *VirtualController) Dels(ctx *gin.Context, entity *dbinfo.TableInfo) (bool, string, interface{}) {
	var ids []interface{}

	params := ginutil.GetParams(ctx)
	if list, ok := params["ids"].([]interface{}); ok {
		ids = list
	}

	return GetService(entity.DbName, entity.Name).Dels(ctx, entity, ids)
}

// HandleFileDownload 处理文件下载
func (c *VirtualController) HandleFileDownload(ctx *gin.Context) (bool, string, interface{}) {
	owner := ctx.Param("owner")
	file := ctx.Param("file")

	// 这里实现文件下载逻辑
	// 注意安全检查，防止目录遍历攻击
	ctx.FileAttachment("path/to/files/"+owner+"/"+file, file)

	return true, "", nil
}

// HandleFileUpload 处理文件上传
func (c *VirtualController) HandleFileUpload(ctx *gin.Context) (bool, string, interface{}) {
	owner := ctx.Param("owner")
	file := ctx.Param("file")

	// 获取上传文件
	uploadedFile, err := ctx.FormFile("file")
	if err != nil {
		Log.Error("获取上传文件异常", err)
		return false, "获取上传文件异常", 9001
	}

	// 这里实现文件保存逻辑
	// 注意安全检查，防止目录遍历攻击
	dst := "path/to/uploads/" + owner + "/" + file
	if err := ctx.SaveUploadedFile(uploadedFile, dst); err != nil {
		Log.Error("保存上传文件异常", err)
		return false, "获取上传文件异常", 9001
	}

	return true, "文件上传成功", 9999
}
